<template>
  <div>
    <!-- <el-form-item label="占位内容">
      <el-input v-model="data.placeholder"
                clearable
                placeholder="占位内容"></el-input>
    </el-form-item> -->
    <div class="el-form-item el-form-item--small el-form--label-top">
      <label class="el-form-item__label" style="padding: 0">字典配置：</label>
      <div class="el-form-item__content">
        <el-tabs v-model="localData.dicOption" stretch @tab-click="handleTabClick">
          <el-tab-pane label="静态数据" name="static">
            <el-tree
              ref="tree"
              :data="localData.dicData"
              default-expand-all
              draggable
              node-key="value"
              :expand-on-click-node="false"
            >
              <template #default="{ node, data: nodeData }">
                <span class="custom-tree-node">
                  <span>{{ node.label }}</span>
                  <span>
                    <el-button
                      link
                      size="default"
                      icon="el-icon-plus"
                      @click="handleNodeAdd(nodeData)"
                    />
                    <!--                <el-button class="warning" link size="mini" icon="el-icon-edit"-->
                    <!--                           @click="handleNodeEdit(data)"></el-button>-->
                    <el-button
                      class="danger"
                      link
                      size="default"
                      icon="el-icon-delete"
                      @click="handleNodeRemove(node, nodeData)"
                    />
                  </span>
                </span>
              </template>
            </el-tree>
            <div style="margin-left: 22px">
              <el-button link @click="handleParentNodeAdd">添加父级 </el-button>
            </div>
          </el-tab-pane>
          <el-tab-pane label="远端数据" name="remote">
            网址
            <el-input v-model="localData.dicUrl" size="default" placeholder="远端数据字典网址" />
            远程搜索
            <el-switch v-model="localData.remote" /><br />
            请求方法
            <el-select
              v-model="localData.dicMethod"
              size="default"
              placeholder="请求方法"
              style="width: 100%"
            >
              <el-option label="POST" value="post" />
              <el-option label="GET" value="get" />
            </el-select>
            <p v-if="localData.dicMethod == 'post'">
              请求参数
              <avue-dynamic v-model="localData.dicQueryConfig" :children="option" />
            </p>
            <p v-if="localData.dicUrl">
              返回结构
              <monaco-editor
                v-model="dicFormatter"
                height="80"
                :keyIndex="`dict-formatter-${localData.prop}`"
                :options="options"
              />
            </p>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
    <div class="el-form-item el-form-item--small el-form--label-top">
      <label class="el-form-item__label" style="padding: 0">字典key配置：</label>
      <div class="el-form-item__content">
        <ul>
          <li v-for="(value, key) in localData.props" :key="key">
            <span style="width: 50px">{{ key }}</span>
            <el-input size="default" v-model="localData.props[key]" placeholder="key配置" />
          </li>
        </ul>
      </div>
    </div>
    <el-form-item v-if="localData.dicOption == 'remote'" label="重新请求字典(crud)">
      <el-switch v-model="localData.dicFlag" />
    </el-form-item>
    <div class="el-form-item el-form-item--small el-form--label-top">
      <label class="el-form-item__label" style="padding: 0">级联配置：</label>
      <div class="el-form-item__content">
        <draggable
          tag="ul"
          :list="localData.cascaderItem || localData.cascader"
          :group="{ name: 'cascaderItem' }"
          ghost-class="ghost"
          handle=".drag-item"
        >
          <li v-for="(item, index) in localData.cascaderItem || localData.cascader" :key="index">
            <i
              class="drag-item el-icon-s-operation"
              style="font-size: 16px; margin: 0 5px; cursor: move"
            ></i>
            <el-input
              v-if="avueVersion('2.9.0')"
              size="default"
              v-model="localData.cascaderItem[index]"
              clearable
              placeholder="级联属性值"
            />
            <el-input
              v-else
              size="default"
              v-model="localData.cascader[index]"
              clearable
              placeholder="级联属性值"
            />
            <el-button
              @click="handleRemoveCascaderItemFields(index)"
              circle
              plain
              type="danger"
              size="default"
              icon="el-icon-minus"
              style="padding: 4px; margin-left: 5px"
            />
          </li>
        </draggable>
        <div style="margin-left: 22px">
          <el-button link @click="handleAddCascaderItemFields">添加列</el-button>
        </div>
      </div>
    </div>
    <template v-if="localData.type == 'tree'">
      <el-form-item label="当有子级时,是否可选择父级" label-width="200px">
        <el-switch v-model="localData.parent" />
      </el-form-item>
    </template>
    <template v-if="localData.type == 'cascader'">
      <el-form-item label="选项分隔符" label-width="100px">
        <el-input v-model="localData.separator" clearable placeholder="选项分隔符" />
      </el-form-item>
      <el-form-item label="是否显示选中值的完整路径" label-width="200px">
        <el-switch v-model="localData.showAllLevels" />
      </el-form-item>
      <el-form-item label="是否可搜索" label-width="100px">
        <el-switch v-model="localData.filterable" />
      </el-form-item>
    </template>
    <el-form-item label="是否多选">
      <el-switch v-model="localData.multiple" />
    </el-form-item>
    <el-form-item
      v-if="localData.type == 'tree' && localData.multiple"
      label="勾选时，父子不关联"
      label-width="160px"
    >
      <el-switch v-model="localData.checkStrictly" />
    </el-form-item>

    <drag-dialog v-model="dialogVisible" :rules="dialogRules" :before-close="beforeClose">
      <el-form ref="dialogForm" :model="dialogForm" label-width="80px">
        <el-form-item label="label">
          <el-input v-model="dialogForm.label" placeholder="label" />
        </el-form-item>
        <el-form-item label="value">
          <el-input v-model="dialogForm.value" placeholder="value" :type="dialogInputType">
            <template #append>
              <el-select v-model="dialogInputType" placeholder="数据类型" style="width: 100px">
                <el-option label="String" value="text" />
                <el-option label="Number" value="number" />
              </el-select>
            </template>
          </el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="handleDialogAdd" v-if="dialogStatus == 'add'"
          >确 定</el-button
          >
          <!--        <el-button type="primary" @click="handleDialogUpdate" v-else>确 定</el-button>-->
        </span>
      </template>
    </drag-dialog>
  </div>
</template>
<script>
import MonacoEditor from '../../utils2/monaco-editor'

export default {
  name: 'ConfigTree',
  components: { MonacoEditor },
  props: {
    data: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      dialogForm: {},
      dialogVisible: false,
      dialogRules: {
        label: { required: true, message: '请输入label' },
        value: { required: true, message: '请输入value' }
      },
      dialogStatus: 'add',
      selectData: undefined,
      dialogInputType: 'text',
      option: {
        column: [
          {
            type: 'input',
            prop: 'key',
            label: 'key'
          },
          {
            type: 'input',
            prop: 'value',
            label: 'value'
          }
        ]
      },
      options: {
        fullScreen: true,
        minimap: {
          enabled: false
        }
      },
      dicFormatter: '',
      localData: {}
    }
  },
  watch: {
    data: {
      handler(newVal) {
        if (newVal) {
          this.localData = newVal
        }
      },
      deep: true,
      immediate: true
    },
    localData: {
      handler(newVal) {
        this.$emit('update:data', newVal)
      },
      deep: true
    },
    'localData.prop': {
      handler() {
        if (!this.avueVersion('2.9.0') && this.localData.cascaderItem) {
          this.localData.cascader = this.localData.cascaderItem
          // this.$set(this.localData, 'cascader', this.localData.cascaderItem)
          delete this.localData.cascaderItem
          // this.$delete(this.localData, 'cascaderItem')
        }
        const { dicFormatter } = this.localData
        this.dicFormatter = dicFormatter
          ? dicFormatter + ''
          : '(res) => {\r\n  return res.data\r\n}'
      },
      immediate: true
    },
    dicFormatter: {
      handler(val) {
        try {
          this.localData.dicFormatter = eval(val)
        } catch (e) {
          // console.error(e)
        }
      }
    }
  },
  methods: {
    handleRemoveCascaderItemFields(index) {
      if (this.avueVersion('2.9.0')) this.localData.cascaderItem.splice(index, 1)
      else this.localData.cascader.splice(index, 1)
    },
    handleAddCascaderItemFields() {
      if (this.avueVersion('2.9.0')) {
        if (!this.localData.cascaderItem) {
          this.localData.cascaderItem = []
          // this.$set(this.localData, 'cascaderItem', [])
        }
        this.localData.cascaderItem.push('')
      } else {
        if (!this.localData.cascader) {
          this.localData.cascader = []
          // this.$set(this.localData, 'cascader', [])
          delete this.localData.cascaderItem
        }
        this.localData.cascader.push('')
      }
    },
    handleTabClick({ name }) {
      if (name == 'remote' && !this.localData.dicQueryConfig) this.localData.dicQueryConfig = []
    },
    handleParentNodeAdd() {
      this.selectData = undefined
      this.dialogStatus = 'add'
      this.dialogVisible = true
    },
    handleNodeAdd(data) {
      this.selectData = data
      this.dialogStatus = 'add'
      this.dialogVisible = true
    },
    handleNodeRemove(node, data) {
      const parent = node.parent
      const children = parent.data.children || parent.data
      const index = children.findIndex((d) => d.id === data.id)
      children.splice(index, 1)
    },
    handleDialogAdd() {
      this.$refs.dialogForm.validate((valid) => {
        if (valid) {
          const { label, value } = this.dialogForm
          const node = this.$refs.tree.getNode(value)
          if (node) this.$message.error('value重复')
          else {
            const data = this.selectData
            const newNode = {
              label,
              value: this.dialogInputType == 'number' ? new Number(value) : value
            }
            if (data) {
              if (!data.children) {
                data.children = []
              }
              data.children.push(newNode)
              // this.$set(data, 'children', [])
            } else {
              this.localData.dicData[this.localData.dicData.length] = newNode
              // this.$set(this.localData.dicData, this.localData.dicData.length, newNode)
            }
            this.beforeClose()
          }
        }
      })
    },
    beforeClose() {
      this.$refs.dialogForm.clearValidate()
      this.dialogForm = {}
      this.dialogVisible = false
    }
  }
}
</script>
<style lang="scss" scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
